﻿#include "WRWavePlayRoutine.h"
#include "WRWavePlayThread.h"
#include <QAudioDeviceInfo>
#include <QCoreApplication>
#include "../WRSoft-Utility/WRBasics.h"

//波形播放线程。
static WRWavePlayThread* g_wavePlayThread = 0;

//波形播放事件。
static int g_wavePlayEvent = QEvent::registerEventType();
//波形播放音量事件。
static int g_wavePlayVolumeEvent = QEvent::registerEventType();

//表示波形播放事件。
class WRWavePlayEvent : public QEvent
{
private:
    WRWavePlayBuffer* m_buffer;
    bool m_action;

public:
    //初始化波形播放事件。
    WRWavePlayEvent(WRWavePlayBuffer* buffer, bool action = true)
        : QEvent((QEvent::Type)g_wavePlayEvent)
    {
        m_buffer = buffer;
        m_buffer->addRef();
        m_action = action;
    }
    //清理当前对象所占用的相关资源。
    ~WRWavePlayEvent()
    {
        m_buffer->release();
    }

    //获取行为。
    inline bool action(void)
    {
        return m_action;
    }
    //获取缓存。
    inline WRWavePlayBuffer* buffer(void)
    {
        return m_buffer;
    }
};
//表示波形播放音量事件。
class WRWavePlayVolumeEvent : public QEvent
{
private:
    float m_value;

public:
    //初始化音量事件。
    WRWavePlayVolumeEvent(float value)
        : QEvent((QEvent::Type)g_wavePlayVolumeEvent)
    {
        m_value = value;
    }

    //获取音量值。
    inline float value(void) const
    {
        return m_value;
    }
};

//初始化播放例程。
WRWavePlayRoutine::WRWavePlayRoutine()
{
    if (g_wavePlayThread)
        g_wavePlayThread->addRef();
    else
        g_wavePlayThread = new WRWavePlayThread();
    moveToThread(g_wavePlayThread);

    m_buffer = 0;
    m_output = 0;
    m_stream = 0;
    m_volume = 0.6F;
    m_channel = WRWavePlayer::DualChannel;
}
//释放当前对象所占用的相关资源。
WRWavePlayRoutine::~WRWavePlayRoutine()
{
    g_wavePlayThread->release();
}

//执行消息处理。
bool WRWavePlayRoutine::event(QEvent * e)
{
    if(e->type() == g_wavePlayEvent)
    {
        WRWavePlayEvent* event = static_cast<WRWavePlayEvent*>(e);
        if (event->action())
        {
            //缓存引用增加。
            event->buffer()->addRef();
            //初始化音频格式
            QAudioFormat format;
            {
                format.setSampleRate(event->buffer()->sampleRate());
                format.setSampleSize(16);
                format.setChannelCount(2);
                format.setSampleType(QAudioFormat::SignedInt);
                format.setByteOrder(QAudioFormat::LittleEndian);
                static QString codec = QStringLiteral("audio/pcm");
                format.setCodec(codec);
            }
            //创建音频输出对象
            QAudioDeviceInfo device(QAudioDeviceInfo::defaultOutputDevice());
            if ((!device.isNull()) && device.isFormatSupported(format))
            {
                m_output = new QAudioOutput(format);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
                m_output->setVolume(m_volume);
#endif
                m_stream = event->buffer()->readData(m_channel);
                m_output->start(m_stream);
            }
        }
        else
        {
            //停止播放并删除资源。
            if (m_output)
            {
                m_output->stop();
                delete m_output;
                delete m_stream;
            }
            //释放缓存引用。
            event->buffer()->release();
        }
        return true;
    }
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
    else if (e->type() == g_wavePlayVolumeEvent)
    {
        WRWavePlayVolumeEvent* event = static_cast<WRWavePlayVolumeEvent*>(e);
        if (m_output)
        {
            m_output->setVolume(event->value());
        }
        return true;
    }
#endif
    else
    {
        return QObject::event(e);
    }
}

//设置音量，音量范围0~1。
void WRWavePlayRoutine::volume(float value)
{
    m_volume = value;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
    QCoreApplication::postEvent(this, new WRWavePlayVolumeEvent(value));
#endif
}
//设置声道。
void WRWavePlayRoutine::channel(WRWavePlayer::Channel value)
{
    m_channel = value;
}

//初始化播放器并开发播放。
void WRWavePlayRoutine::start(int sampleRate)
{
    if (m_buffer)
    {
        //如果采样率相同，则直接连续播放
        if (m_buffer->sampleRate() == sampleRate)
        {
            return;
        }
        //执行停止处理
        QCoreApplication::postEvent(this, new WRWavePlayEvent(m_buffer, false));
        m_buffer->release();
        m_buffer = 0;
    }
    //初始化缓存
    m_buffer = new WRWavePlayBuffer(sampleRate);
    //启动播放对象
    QCoreApplication::postEvent(this, new WRWavePlayEvent(m_buffer, true));
}
//停止播放。
void WRWavePlayRoutine::stop(void)
{
    if (m_buffer)
    {
        QCoreApplication::postEvent(this, new WRWavePlayEvent(m_buffer, false));
        m_buffer->release();
        m_buffer = 0;
    }
}
